<template>
  <TresGroup>
    <!-- 飞鸟 -->
    <!-- <Bird :target-position="targetPosition" /> -->
    <!-- 飞线 -->
    <!-- <Flylines :lines="lines" /> -->
    <!-- 点击后的城市maker -->
    <TresHtml
      :style="{
        transition: 'all 0.2s',
        opacity: makerVisible ? 1 : 0,
        transform: `scale(${makerVisible ? 1 : 0.25})`,
        userSelect: 'none',
        width: '200px',
        fontFamily: 'zaozigongfangtianliti',
        color: '#242424',
      }"
      :position="makerPosition"
    >
      <h3>{{ makerValue }}</h3>
    </TresHtml>
    <!-- 城市名称 -->
    <TresGroup
      :rotation="[0, Math.PI * 1.1, Math.PI]"
      :position-y="baseHeight + midHeightScale * baseHeight + 0.01"
    >
      <TresGroup v-for="(item, index) in blocks" :key="'city_' + index">
        <Text3D
          ref="namesRef[index]"
          font="./MFTianLiNoncommercial_Regular.json"
          :position="[
            (item.properties.centroid[0] - mapCenter[0]) * scale,
            0.01,
            (item.properties.centroid[1] - mapCenter[1]) * scale,
          ]"
          :rotation="[-Math.PI * 0.5, Math.PI, Math.PI]"
          v-bind="textConfig"
        >
          {{ item.properties.name }}
          <TresMeshBasicMaterial color="#ffffff" transparent />
        </Text3D>
      </TresGroup>
    </TresGroup>
    <!-- 城市block -->
    <TresGroup
      :rotation="[-Math.PI * 0.5, 0, Math.PI * 0.09]"
      :position-y="baseHeight + midHeightScale * baseHeight + 0.01"
    >
      <TresGroup v-for="(item, index) in blocks" :key="'top_' + index">
        <TresMesh
          :scale="[1, 1, topHeightScale]"
          :geometry="item.children[0].geometry"
          @click="handleClick(index)"
        >
          <TresMeshPhysicalMaterial
            v-bind="materialConfig"
            :transmission="Math.sqrt(item.properties.value / maxValue)"
            :roughness="Math.sqrt(item.properties.value / maxValue)"
          />
          <Edges color="#ffffff" />
        </TresMesh>
      </TresGroup>
    </TresGroup>
  </TresGroup>
</template>

<script setup>
import { ref, computed, onMounted } from "vue";
import { gsap } from "gsap";
// import Bird from "../../Decoration/Bird.vue";
// import Flylines from "../../Decoration/Flylines.vue";
import { Text3D, Edges } from "@tresjs/cientos";

const props = defineProps({
  baseHeight: {
    type: Number,
    required: true,
  },
  midHeightScale: {
    type: Number,
    required: true,
  },
  topHeightScale: {
    type: Number,
    required: true,
  },
  blocks: {
    type: Array,
    required: true,
  },
  values: {
    type: Object,
    required: true,
  },
  mapCenter: {
    type: Array,
    required: true,
  },
});

// 材质配置
const materialConfig = {
  color: "#9cb8e4",
  clearcoat: 0.5,
  reflectivity: 0.35,
  ior: 1.3,
};

// 文本配置
const textConfig = {
  curveSegments: 32,
  bevelEnabled: true,
  bevelSize: 0,
  bevelThickness: 0,
  height: 0.02,
  letterSpacing: 0,
  size: 0.25,
};

const scale = 3.15;

// 状态管理
const blocksRef = ref([]);
const namesRef = ref([]);
const makerVisible = ref(false);
const makerPosition = ref([0, 2, 0]);
const makerValue = ref("");
const lines = ref({ children: [] });
const targetPosition = ref({ x: 0, z: 0 });

// 计算属性：最大值
const maxValue = computed(() => {
  return Math.max(...Object.values(props.values.features));
});

// 计算排名信息
const rankInfo = computed(() => {
  let info = Object.keys(props.values.features).map(
    (key) => `${key} ${props.values.features[key]}`
  );
  info.sort((a, b) => b.split(" ")[1] - a.split(" ")[1]);
  return info.map((item, index) => index + 1 + "." + item);
});

// 排名映射
const rank = computed(() => {
  const result = {};
  rankInfo.value.forEach((item) => {
    result[item.split(".")[1].split(" ")[0]] = item;
  });
  return result;
});

// 点击处理函数
const handleClick = (index) => {
  lines.value = { children: [] };
  // 第二次点击选中的地图，让其恢复默认状态
  if (blocksRef.value[index] && blocksRef.value[index].scale.z === 0.8) {
    handleSecondClick(index);
  } else {
    handleFirstClick(index);
  }
};

const handleFirstClick = (index) => {
  let tempArr = [];
  props.blocks.forEach((block, i) => {
    if (i !== index) {
      const startX =
        (props.blocks[index].properties.center[0] - props.mapCenter[0]) * scale;
      const startZ =
        -(props.blocks[index].properties.center[1] - props.mapCenter[1]) *
        scale;
      const endX = (block.properties.center[0] - props.mapCenter[0]) * scale;
      const endZ = -(block.properties.center[1] - props.mapCenter[1]) * scale;
      tempArr.push({
        start: [
          startX,
          props.baseHeight * (1 + props.midHeightScale + props.topHeightScale) +
            0.3,
          startZ,
        ],
        end: [
          endX,
          props.baseHeight * (1 + props.midHeightScale + props.topHeightScale) +
            0.3,
          endZ,
        ],
        mid: [
          startX + (endX - startX) / 5,
          props.baseHeight * (1 + props.midHeightScale + props.topHeightScale) +
            2,
          startZ + (endZ - startZ) / 5,
        ],
      });
    }
  });
  lines.value = { children: [...tempArr] };

  // maker
  const region = props.blocks[index].properties.name;
  makerVisible.value = true;
  makerValue.value = rank.value[region];
  makerPosition.value = [
    (props.blocks[index].properties.center[0] - props.mapCenter[0]) * scale,
    2,
    -(props.blocks[index].properties.center[1] - props.mapCenter[1]) * scale,
  ];

  // block
  blocksRef.value.forEach((block, lastIndex) => {
    if (block && block.scale.z === 0.8) {
      gsap.to(blocksRef.value[lastIndex].scale, {
        duration: 0.3,
        z: props.topHeightScale,
      });
      blocksRef.value[lastIndex].material.color = new THREE.Color("#9cb8e4");
      if (namesRef.value[lastIndex]) {
        namesRef.value[lastIndex].material.opacity = 1;
      }
    }
  });

  if (blocksRef.value[index]) {
    gsap.to(blocksRef.value[index].scale, { duration: 0.3, z: 0.8 });
    blocksRef.value[index].material.color = new THREE.Color("#ffb47e");
    if (namesRef.value[index]) {
      namesRef.value[index].material.opacity = 0;
    }
  }

  // bird
  if (tempArr.length > 0) {
    targetPosition.value = { x: tempArr[0].start[0], z: tempArr[0].start[2] };
  }
};

const handleSecondClick = (index) => {
  makerVisible.value = false;
  makerValue.value = "";
  makerPosition.value = [0, 2, 0];

  if (blocksRef.value[index]) {
    gsap.to(blocksRef.value[index].scale, {
      duration: 0.3,
      z: props.topHeightScale,
    });
    blocksRef.value[index].material.color = new THREE.Color("#9cb8e4");
    if (namesRef.value[index]) {
      namesRef.value[index].material.opacity = 1;
    }
  }
};

// 初始化引用
onMounted(() => {
  blocksRef.value = Array(props.blocks.length).fill(null);
  namesRef.value = Array(props.blocks.length).fill(null);
});
</script>
